
package com.calendar.guos.client.calendar;


import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;

import com.calendar.guos.client.data.LocalDataStore;
import com.calendar.guos.client.panels.LoginStatusPanel;
import com.google.gwt.accounts.client.AuthSubStatus;
import com.google.gwt.accounts.client.User;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dev.shell.CloseButton.Callback;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.gdata.client.DateTime;
import com.google.gwt.gdata.client.EventEntry;
import com.google.gwt.gdata.client.EventEntryCallback;
import com.google.gwt.gdata.client.GData;
import com.google.gwt.gdata.client.GDataRequestParameters;
import com.google.gwt.gdata.client.GDataSystemPackage;
import com.google.gwt.gdata.client.Recurrence;
import com.google.gwt.gdata.client.Reminder;
import com.google.gwt.gdata.client.When;
import com.google.gwt.gdata.client.Where;
import com.google.gwt.gdata.client.atom.Text;
import com.google.gwt.gdata.client.calendar.CalendarAclFeed;
import com.google.gwt.gdata.client.calendar.CalendarAclFeedCallback;
import com.google.gwt.gdata.client.calendar.CalendarEntry;
import com.google.gwt.gdata.client.calendar.CalendarEntryCallback;
import com.google.gwt.gdata.client.calendar.CalendarEventEntry;
import com.google.gwt.gdata.client.calendar.CalendarEventEntryCallback;
import com.google.gwt.gdata.client.calendar.CalendarEventFeed;
import com.google.gwt.gdata.client.calendar.CalendarEventFeedCallback;
import com.google.gwt.gdata.client.calendar.CalendarEventQuery;
import com.google.gwt.gdata.client.calendar.CalendarExtendedProperty;
import com.google.gwt.gdata.client.calendar.CalendarFeed;
import com.google.gwt.gdata.client.calendar.CalendarFeedCallback;
import com.google.gwt.gdata.client.calendar.CalendarService;
import com.google.gwt.gdata.client.calendar.ColorProperty;
import com.google.gwt.gdata.client.calendar.HiddenProperty;
import com.google.gwt.gdata.client.calendar.TimeZoneProperty;
import com.google.gwt.gdata.client.impl.CallErrorException;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;



/**
 * GcalendarData is the mediator between our client and google
 */
public class GcalendarData extends Composite{


  public CalendarService service;
  
  //Where all calendars and events will be stored locally
  public LocalDataStore dataStore = new LocalDataStore();

  
  //Login/Logout status screen
  public LoginStatusPanel loginStatusPanel;

  
  //Main Calendar feed URI
  public final String scope = "http://www.google.com/calendar/feeds/";
  //Insert google data API key here
  public String GDATA_API_KEY;
  //After logging in where google redirects the user
  String nextUrl = "http://www.example.com/RetrieveToken.jsp";
  
  //Authentication options
  boolean secure = false;  // set secure=true to request secure AuthSub tokens
  boolean session = true;
  
  //Google calendar URIs
  public CalendarFeed ownCalendarFeed;
  String ownCalendarURL = "http://www.google.com/calendar/feeds/default/owncalendars/full";
  String allCalendarURL = "http://www.google.com/calendar/feeds/default/allcalendars/full";
  
  /**
   * Setup the Calendar service 
   * create the main content panel.
   * If the user is not logged on to Calendar display a message,
   * otherwise start the demo by creating a calendar.
   */
  public GcalendarData() {
	  

	  loginStatusPanel = new LoginStatusPanel();
	  

    if (GData.isLoaded(GDataSystemPackage.CALENDAR)) {
    	   Window.alert("Package is loaded");
    	} else {
    	   GData.loadGDataApi("MyApiKey",
    	      new Runnable() {
    	        public void run() {
//    	             String scope = "http://www.google.com/calendar/feeds/";
//    	             User.login(scope);
    	        	 loginStatusPanel.update();
    	             //remaining code comes in here. you may create a new method
    	             //and call it from here.
    	        }
    	      },
    	      GDataSystemPackage.CALENDAR);
    	}

  }
  


  /**
   * Sends new calendar to google
   * @param calendarsFeedUri the users calendar URI we want to send to
   * @param entry the new calendar
   */
  public void addNewCalendarTWO(String calendarsFeedUri, CalendarEntry entry ){
	  	service = CalendarService.newInstance("GUoS_Calendar_AddNewCalendar");
	    //Inner class insert 
	    service.insertEntry(calendarsFeedUri, entry,
	        new CalendarEntryCallback() {
	      public void onFailure(CallErrorException caught) {
	        showStatus("An error occurred while retrieving the Calendar feed: " +
	            caught.getMessage(), true);
	        
	      }
	      public void onSuccess(CalendarEntry result) {
	        showStatus("Created a Calendar entry titled '" + 
	            result.getTitle().getText() + "'", false);
	      }
	    });
	    

  }
  
  /**
   * 
   * @param eventsFeedUri The uri of the events feed into which to 
   * insert the new event
   */
  public void createEventRecurring(String eventsFeedUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_CreateNewEventRecurring");
    showStatus("Creating event...", false);
    CalendarEventEntry eventEntry = CalendarEventEntry.newInstance();
    eventEntry.setTitle(Text.newInstance());
    eventEntry.getTitle().setText(
        "GWT-Calendar-Client: insert recurring event");
    Recurrence recurrence = Recurrence.newInstance();
    String icalBreak = "\r\n";
    String recurrenceString = 
        "DTSTART;TZID=America/Los_Angeles:20090101T080000" + icalBreak +
        "DTEND;TZID=America/Los_Angeles:20090101T090000" + icalBreak +
        "RRULE:FREQ=WEEKLY;UNTIL=20090701T160000Z;";
    recurrence.setValue(recurrenceString);
    eventEntry.setRecurrence(recurrence);
    service.insertEntry(eventsFeedUri, eventEntry,
        new CalendarEventEntryCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while creating a Calendar event: " + 
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEventEntry result) {
        showStatus("Created a recurring event.", false);
      }
    });
  }
  
  /**
   * 
   * @param eventsFeedUri The uri of the events feed into which to 
   * insert the new event
   */
  @SuppressWarnings("deprecation")
  public void createEventWithExtendedProperty(String eventsFeedUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_CreateEventWithExtendedProp");
    showStatus("Creating event reminder...", false);
    CalendarEventEntry entry = CalendarEventEntry.newInstance();
    entry.setTitle(Text.newInstance());
    entry.getTitle().setText("GWT-Calendar-Client: add extended property");
    When when = When.newInstance();
    Date startTime = new Date();
    Date endTime = new Date();
    endTime.setHours(endTime.getHours() + 1);
    when.setStartTime(DateTime.newInstance(startTime));
    when.setEndTime(DateTime.newInstance(endTime));
    entry.addTime(when);
    CalendarExtendedProperty extendedProp =
        CalendarExtendedProperty.newInstance();
    extendedProp.setName("mydata");
    extendedProp.setValue("xyz");
    entry.addExtendedProperty(extendedProp);
    service.insertEntry(eventsFeedUri, entry,
        new CalendarEventEntryCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while creating a Calendar event " +
            "reminder: " + caught.getMessage(), true);
      }
      public void onSuccess(CalendarEventEntry result) {
        showStatus("Created an event with an extended property.", false);
      }
    });
  }
  
  /**
   * 
   * @param eventsFeedUri The uri of the events feed into which to 
   * insert the new event
   */
  @SuppressWarnings("deprecation")
  public void createSingleEvent(String eventsFeedUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_CreateSingleEvent");
    showStatus("Creating Calendar event...", false);
    CalendarEventEntry eventEntry = CalendarEventEntry.newInstance();
    eventEntry.setTitle(Text.newInstance());
    eventEntry.getTitle().setText("GWT-Calendar-Client: insert event");
    Date startDate = new Date();
    Date endDate = new Date();
    endDate.setHours(endDate.getHours() + 1);
    When when = When.newInstance();
    when.setStartTime(DateTime.newInstance(startDate));
    when.setEndTime(DateTime.newInstance(endDate));
    eventEntry.addTime(when);
    service.insertEntry(eventsFeedUri, eventEntry,
        new CalendarEventEntryCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while creating a Calendar event: " + 
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEventEntry result) {
        showStatus("Created a Calendar event taking place in the next hour.",
            false);
      }
    });
  }
  
  /**
   * 
   * @param calendarsFeedUri The uri of the calendars feed
   */
  public void findCalendars(String calendarsFeedUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_FindCalendars");
    showStatus("Loading calendars...", false);
    service.getOwnCalendarsFeed(calendarsFeedUri, new CalendarFeedCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while retrieving the Calendar feed: " + 
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarFeed result) {
        CalendarEntry[] entries = result.getEntries();
        if (entries.length == 0) {
          showStatus("You have no calendars.", false);
        } else {
          CalendarEntry targetCalendar = null;
          for (CalendarEntry entry : entries) {
            String title = entry.getTitle().getText();
            if (title.startsWith("GWT-Calendar-Client")) {
              targetCalendar = entry;
              break;
            }
          }
          if (targetCalendar == null) {
            showStatus("Did not find a calendar entry whose title starts " +
                "with the prefix 'GWT-Calendar-Client'.", false);
          } else {
            String calendarEntryUri = targetCalendar.getSelfLink().getHref();
            deleteCalendar(calendarEntryUri);
          }
        }
      }
    });
  }
  
  /**
   * Delete a calendar entry using the Calendar service and
   * the calendar entry uri.
   * On success and failure, display a status message.
   * 
   * @param calendarEntryUri The uri of the calendar entry to delete
   */
  public void deleteCalendar(String calendarEntryUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_DeleteCalendarURI");
    showStatus("Deleting calendar...", false);
    service.deleteEntry(calendarEntryUri, new CalendarEntryCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while deleting a calendar: " + 
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEntry result) {
        showStatus("Deleted a calendar.", false);
      }
    });
  }
  
  /**
   * Finds specified calendar and deletes it
   * @param calendarsFeedUri
   * @param specificCalendarName
   */
  public void deleteCalendar(String calendarsFeedUri, final String specificCalendarName) {
	  	service = CalendarService.newInstance("GUoS_Calendar_DeleteCalendarName");
	    service.getOwnCalendarsFeed(calendarsFeedUri, new CalendarFeedCallback() {
	    	/**
	    	 * On fail we output error message
	    	 */
	    	public void onFailure(CallErrorException caught) {
	        showStatus("An error occurred while retrieving the Calendar feed: " + 
	            caught.getMessage(), true);
	      }
	      
	      /**
	       * Got our own calendar feed now find the specific calendar we are looking for
	       * @param result our users own calendar feed
	       */
	      public void onSuccess(CalendarFeed result) {
	        CalendarEntry[] entries = result.getEntries();
	        
	        
	        if (entries.length == 0) {
	          showStatus("You have no calendars.", false);
	        } 
	        else {
	        	
	          CalendarEntry targetCalendar = null;
	          
	          //look for our specific calendar
	          for (CalendarEntry entry : entries) {
	        	  
	            String title = entry.getTitle().getText();
	            //If we found our calendar get the entry
	            if (title.startsWith(specificCalendarName)) {
	              targetCalendar = entry;
	              break;
	            }
	          }
	          //We didn't find the asked for calendar, let the user know
	          //maybe he needs to make one?
	          if (targetCalendar == null) {
	            showStatus("Did not find a calendar entry whose title starts " +
	                "with the prefix 'GWT-Calendar-Client'.", false);
	          } 
	          else {
	        	  //We found our calendar grab the calendar we were looking fors URI
	            String calendarEntryUri = targetCalendar.getSelfLink().getHref();
	            
	            // delete event chea boy!
	            deleteCalendar(calendarEntryUri);

	          }
	        }
	      }
	    });
	  }

  /**
   * Displays a set of Calendar event entries in a tabular fashion with
   * the help of a GWT FlexTable widget. The data fields Title, URL 
   * and Updated are displayed.
   * 
   * @param entries The Calendar event entries to display.
   */
   public void showDataQueryEventsByDate(CalendarEventEntry[] entries) {
     //loginStatusPanel.clear();
	 loginStatusPanel.refresh();
     String[] labels = new String[] { "Title", "URL", "Updated" };
     loginStatusPanel.insertRow(0);
     for (int i = 0; i < labels.length; i++) {
       loginStatusPanel.addCell(0);
       loginStatusPanel.setWidget(0, i, new Label(labels[i]));
       loginStatusPanel.getFlexCellFormatter().setStyleName(0, i, "hm-tableheader");
     }
     for (int i = 0; i < entries.length; i++) {
       CalendarEventEntry entry = entries[i];
       int row = loginStatusPanel.insertRow(i + 1);
       loginStatusPanel.addCell(row);
       loginStatusPanel.setWidget(row, 0, new Label(entry.getTitle().getText()));
       loginStatusPanel.addCell(row);
       String link = entry.getHtmlLink().getHref();
       loginStatusPanel.setWidget(row, 1, 
           new HTML("<a href=\"" + link + "\">" + link + "</a>"));
       loginStatusPanel.addCell(row);
       loginStatusPanel.setWidget(row, 2, 
           new Label(entry.getUpdated().getValue().getDate().toString()));
     }
   }
   CalendarEventEntry[] rtCalEntriesGetEvents = null; 
  /**
   * Retrieve the Calendar events feed using the Calendar service and
   * the events feed uri. In GData all get, insert, update and delete methods
   * always receive a callback defining success and failure handlers.
   * Here, the failure handler displays an error message while the
   * success handler calls showData to display the event entries.
   * 
   * @param eventsFeedUri The uri of the events feed
   */
  public void getEvents(final CalendarEntry calendar, String eventsFeedUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_GetEvents");
	  
    showStatus("Loading events feed...", false);
    rtCalEntriesGetEvents= null;
    service.getEventsFeed(eventsFeedUri, new CalendarEventFeedCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while retrieving the Events feed: " +
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEventFeed result) {
        CalendarEventEntry[] entries =
          (CalendarEventEntry[]) result.getEntries();
        if (entries.length == 0) {
          showStatus("There are no Calendar events.", false);
        } else {
        	//TODO: we want store these events to be our current 
        	//and output those current events to the calendar here
        	//addCalendarEventsToStore(calendar, entries);
        	rtCalEntriesGetEvents = entries;
        
          showDataRetrieveEvents(entries);
        }
      }
    });
 
  }
  
  

  public CalendarEventEntry[] getSpecificCalendarEventsTWO(final String specificCalendarName, String calendarsFeedUri){
	    //showStatus("Loading calendars...", false);
	  rtCalEntriesGetEvents = new CalendarEventEntry[0];
	  service = CalendarService.newInstance("GUoS_Calendar_GetSpecificCalendarEvents");
	    //Inner class to get Own feed
	    service.getOwnCalendarsFeed(calendarsFeedUri, new CalendarFeedCallback() {
	    	/**
	    	 * On fail we output error message
	    	 */
	    	public void onFailure(CallErrorException caught) {
	        showStatus("An error occurred while retrieving the Calendar feed: " + 
	            caught.getMessage(), true);
	      }
	      
	      /**
	       * Got our own calendar feed now find the specific calendar we are looking for
	       * @param result our users own calendar feed
	       */
	      public void onSuccess(CalendarFeed result) {
	        CalendarEntry[] entries = result.getEntries();
	        
	        
	        if (entries.length == 0) {
	          showStatus("You have no calendars.", false);
	        } 
	        else {
	        	
	          CalendarEntry targetCalendar = null;
	          
	          //look for our specific calendar
	          for (CalendarEntry entry : entries) {
	        	  
	            String title = entry.getTitle().getText();
	            //If we found our calendar get the entry
	            if (title.startsWith(specificCalendarName)) {
	              targetCalendar = entry;
	              break;
	            }
	          }
	          //We didn't find the asked for calendar, let the user know
	          //maybe he needs to make one?
	          if (targetCalendar == null) {
	            showStatus("Did not find a calendar entry whose title starts " +
	                "with the prefix 'GWT-Calendar-Client'.", false);
	          } 
	          else {
	        	  //We found our calendar grab the calendar we were looking fors URI
	            String eventFeedLink = targetCalendar.getEventFeedLink().getHref();

	            //get our events woo! and render it to the planner
	            getEvents(targetCalendar, eventFeedLink);
	            //deleteCalendar(calendarEntryUri);
	          }
	        }
	      }
	    });
	    return rtCalEntriesGetEvents;
  }
  
  /**
   * 
   * @param targetCalendar The calendar entry which to update
   */
  public void updateCalendar(CalendarEntry targetCalendar, String calendarTitle, String calendarContent) {
    targetCalendar.setTitle(Text.newInstance());
    targetCalendar.getTitle().setText(
        calendarTitle);
    
    targetCalendar.setContent(Text.newInstance());
    
    targetCalendar.getContent().setText(calendarContent);
    //showStatus("Updating calendar...", false);
    targetCalendar.updateEntry(new CalendarEntryCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while updating a calendar: " +
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEntry result) {
        //showStatus("Updated a calendar.", false);
      }
    });
  }
  

  /**
   * Finds Calendar and adds the given event to it
   * @param calendarsFeedUri
   * @param specificCalendarName
   * @param event
   */
  public void addEventToSpecificCalendarTWO(final String ownCalendarsFeedUri, final String specificCalendarName, final CalendarEventEntry event){
      //showStatus("Loading calendars...", false);
	  service = CalendarService.newInstance("GUoS_Calendar_AddEventSpecificCal");
      Window.alert("Accessing service");
      //Inner class to get Own feed
      service.getOwnCalendarsFeed(ownCalendarsFeedUri, new CalendarFeedCallback() {
      	/**
      	 * On fail we output error message
      	 */
      	public void onFailure(CallErrorException caught) {
      		
      		Window.alert("Error.");
      		showStatus("An error occurred while retrieving the Calendar feed: " + 
      				caught.getMessage(), true);
        }
     
        /**
         * Got our own calendar feed now find the specific calendar we are looking for
         * @param result our users own calendar feed
         */
        public void onSuccess(CalendarFeed result) {
        	Window.alert("In Success.");//TODO: Remove
        	CalendarEntry[] entries = result.getEntries();
          
          
          /*if (entries.length == 0) {
        	  CalendarEntry entry = CalendarEntry.newInstance();
        	  entry.getTitle().setText(specificCalendarName);
        	  addNewCalendarTWO(calendarsFeedUri, entry);*/
        	  
        	  
            //showStatus("You have no calendars.", false);
          //} 
          //else {
          	
            CalendarEntry targetCalendar = null;
            
            //look for our specific calendar
            for (CalendarEntry entry : entries) {
            	String title = entry.getTitle().getText();
            	//If we found our calendar get the entry
            	if (title.startsWith(specificCalendarName)) {
            		targetCalendar = entry;
            		break;
            	}
            }
            //We didn't find the asked for calendar, let the user know
            //maybe he needs to make one?
            if (targetCalendar == null) {
            	
//              showStatus("Did not find a calendar entry whose title starts " +
//                  "with the prefix 'GWT-Calendar-Client'.", false);
            	Window.alert("Calendar not found.");
            	CalendarEntry entry = CalendarEntry.newInstance();
            	entry.setTitle(Text.newInstance());
          	  	entry.getTitle().setText(specificCalendarName);
          	  	entry.setSummary(Text.newInstance());
          	  	entry.getSummary().setText(
          	  		"This is the Google UoS Calendar/Scheduler or GUoS C/S");
          	  	entry.setTimeZone(TimeZoneProperty.newInstance());
          	  	entry.getTimeZone().setValue("America/Regina");
          	  	Where where = Where.newInstance();
          	  	where.setLabel("University of Saskatchewan, Saskatoon, SK");
          	  	where.setValueString("University of Saskatchewan, Saskatoon, SK");
          	  	entry.addLocation(where);
          	  	entry.setHidden(HiddenProperty.newInstance());
          	  	entry.getHidden().setValue(false);
          	  	entry.setColor(ColorProperty.newInstance());
          	  	entry.getColor().setValue(ColorProperty.VALUE_RGB_2952A3);
          	  	addNewCalendarTWO(ownCalendarsFeedUri, entry);
          	  	entries = null;
          	  	
          	  	//addEventToSpecificCalendarTWO(ownCalendarsFeedUri, specificCalendarName, event);
          	  	entries = getAllOwnGoogleCalendars(ownCalendarsFeedUri);

          	  	Window.alert("Grabbed all own calendars again.");
          	  
          	  	for (CalendarEntry currEntry : entries) {
            	  
          	  		String title = currEntry.getTitle().getText();
          	  		Window.alert(title);
          	  		//If we found our calendar get the entry
          	  		if (title.startsWith(specificCalendarName)) {
          	  			targetCalendar = currEntry;
          	  			Window.alert("Found "+title);
          	  			break;
          	  		}
          	  	}
          	  
            } 
            //else {
          	  //We found our calendar grab the calendar we were looking fors URI
            
            	String calendarEntryUri = targetCalendar.getSelfLink().getHref();
            	Window.alert(calendarEntryUri);  
            // add the event bo yah!
            	Window.alert("Adding event.");
            	String calendarName = calendarEntryUri.substring(calendarEntryUri.lastIndexOf('/')+1);
      	  		String specificCalendarEventURI = scope + calendarName + "/private/full";
      	  		Window.alert(calendarEntryUri);
      	  		Window.alert(specificCalendarEventURI);
      	  		addEvent(specificCalendarEventURI, event);
      	  		Window.alert("Done adding event");
            //}

            //}
            //}
        }
      });
  }
  private String rtSpecifiedUri =null;
  
  
public String getSpecifiedCalendarUriTWO(String calendarsFeedUri, final String specificCalendarName){
	service = CalendarService.newInstance("GUoS_Calendar_GetSpecifiedCalendarURI");
    //showStatus("Loading calendars...", false);
    final String rtUri=null;
    //Inner class to get Own feed
    service.getOwnCalendarsFeed(calendarsFeedUri, new CalendarFeedCallback() {
    	/**
    	 * On fail we output error message
    	 */
    	public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while retrieving the Calendar feed: " + 
            caught.getMessage(), true);
      }
      
      /**
       * Got our own calendar feed now find the specific calendar we are looking for
       * @param result our users own calendar feed
       */
      public void onSuccess(CalendarFeed result) {
        CalendarEntry[] entries = result.getEntries();
        
        
        if (entries.length == 0) {
          showStatus("You have no calendars.", false);
        } 
        else {
        	
          CalendarEntry targetCalendar = null;
          
          //look for our specific calendar
          for (CalendarEntry entry : entries) {
        	  
            String title = entry.getTitle().getText();
            //If we found our calendar get the entry
            if (title.startsWith(specificCalendarName)) {
              targetCalendar = entry;
              break;
            }
          }
          
          //We didn't find the asked for calendar, let the user know
          //maybe he needs to make one?
          if (targetCalendar == null) {
            showStatus("Did not find a calendar entry whose title starts " +
                "with the prefix 'GWT-Calendar-Client'.", false);
          } 
          else {
        	  //We found our calendar grab the calendar we were looking fors URI
            rtSpecifiedUri = targetCalendar.getSelfLink().getHref();
            


          }
        }
      }
    });
    
    return rtSpecifiedUri;
}
 
  /**
   * Adds event to calendar with given URI
   * @param specificCalendarURI
   * @param event
   */
  public void addEvent(String specificCalendarURI, CalendarEventEntry event){
	  service = CalendarService.newInstance("GUoS_Calendar_AddEvent");
	    //Send the event to google calendar
	  //String calendarName = specificCalendarURI.substring(specificCalendarURI.lastIndexOf('/'));
	  //String specificCalendarEventURI = this.scope + calendarName + "/private/full";
	    service.insertEntry(specificCalendarURI, event,

	        new CalendarEventEntryCallback() {
	      public void onFailure(CallErrorException caught) {
	    	  Window.alert("Error. Event not added."+ caught.getMessage());
	        showStatus("An error occurred while creating a Calendar event " +
	            "reminder: " + caught.getMessage(), true);
	        	
	      }
	      public void onSuccess(CalendarEventEntry result) {
	    	  Window.alert("Event added to GCal");
	        showStatus("Created a Calendar event.", false);
	        
	      }
	    });


	    
}


 /**
  * Compare method to find a calendar inside a feed
  * @param specificCalendarName
  * @param Calendar entries to find specific calendar
  * @return id the calendar ID of the specificCalendar
  */
public String findCalendarInEntries(String specificCalendarName, CalendarEntry[] calendarEntries) {
	//Cycle through the calenders in ownCalendar feed 
	for (CalendarEntry calendar: calendarEntries){
		  //Compare each calendars name with the one from entries
		  if(calendar.getTitle().getText().startsWith(specificCalendarName)){
			  //we found our specific calendar
			  //Now retrieve it's id
			  
			  /*Get the calendar ID*/
			  String editLink = calendar.getId().getValue();  //For some reason, getId() returns the edit link and not the actual calendar id
			  
			  //debugging
			  System.out.println(editLink);
			  
			  //Parse the actual calendar id from this
			  String id = editLink.substring(editLink.lastIndexOf('/')+1);
			  System.out.println(id);
			  
			  
			  return id;
		  }


	}
	  
	//we didn't find our calendar
	  System.err.println("Calendar not found");
	return null;
}
  /**
   * 
   * @param targetEvent The event entry which to update
   */
  public void updateEvent(CalendarEventEntry targetEvent) {
    targetEvent.setTitle(Text.newInstance());
    targetEvent.getTitle().setText("GWT-Calendar-Client - updated event");
    showStatus("Updating a Calendar event...", false);
    targetEvent.updateEntry(new EventEntryCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while updating a Calendar event: " +
            caught.getMessage(), true);
      }
      public void onSuccess(EventEntry result) {
        showStatus("Updated a Calendar event.", false);
      }
    });
  }

  /**
   * Delete an event entry using the Calendar service and
   * the event entry uri.
   * On success and failure, display a status message.
   * 
   * @param eventEntryUri The uri of the event entry to delete
   * @param etag The etag of the entry to delete
   */
  public void deleteEvent(String eventEntryUri, String etag) {
	  service = CalendarService.newInstance("GUoS_Calendar_DeleteEvent");
    showStatus("Deleting event...", false);
    GDataRequestParameters pars = GDataRequestParameters.newInstance();
    pars.setEtag(etag);
    service.deleteEntry(eventEntryUri,
        new CalendarEventEntryCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while deleting a Calendar event: " +
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEventEntry result) {
        showStatus("Deleted a Calendar event.", false);
      }
    }, pars);
  }
  
  /**
   * Deletes Event with the same title
   * @param calendarsFeedUri
   * @param specificCalendarName
   * @param eventTitle
   * @param all deletes all events with this title
   */
  public void deleteEventByTitle(String calendarsFeedUri, final String specificCalendarName, 
		  /*final String eventTitle*/ final CalendarEventEntry event, final boolean all) {
	  
	  CalendarEntry[] entries = getAllOwnGoogleCalendars(calendarsFeedUri);
	  
	  CalendarEntry targetCalendar = CalendarEntry.newInstance();
	  for (CalendarEntry entry : entries)
	  {
		  if (entry.getTitle().getText().startsWith(specificCalendarName))
		  {
			  targetCalendar = entry;
			  break;
		  }
	  }
	  
	  String calendarEntryUri = targetCalendar.getSelfLink().getHref();
	  String exactGCalendarName = calendarEntryUri.substring(calendarEntryUri.lastIndexOf('/')+1);
	  String specificCalendarUri = scope + exactGCalendarName + "/private/full";
	    //showStatus("Querying for events...", false);
	  service = CalendarService.newInstance("GUoS_Calendar_DeleteEventByTitle");
	  	//Get the events URI for this calendar
	    CalendarEventQuery query =
	        CalendarEventQuery.newInstance(specificCalendarUri);
	    
	    //Find the class's title
	    //query.setFullTextQuery(eventTitle);
	    query.setFullTextQuery(event.getTitle().getText());
	    Window.alert("Calendar feed : " + calendarsFeedUri + "\nEventTitle: " + event.getTitle().getText());
	    
	    service.getEventsFeed(query, new CalendarEventFeedCallback() {
	      public void onFailure(CallErrorException caught) {
	        showStatus("An error occurred while retrieving the Event feed: " +
	            caught.getMessage(), true);
	      }
	      
	      public void onSuccess(CalendarEventFeed result) {
	    	  
	        CalendarEventEntry[] entries = (CalendarEventEntry[]) result.getEntries();
	        //We didn't find any events matching the title
	        if (entries.length == 0) {
	          showStatus(
	              "No events found containing the text 'GWT-Calendar-Client'.",
	              false);
	        } 
	        else {
	        	//delete all with this title
	        	/*if(all){
	                //We found our event must delete
	   	         for(CalendarEventEntry targetEvent: entries){
	   		          String eventEntryUri = targetEvent.getEditLink().getHref();
	   		          deleteEvent(eventEntryUri, targetEvent.getEtag());
	   	         }
	        	}
	        	//delete first one found
	        	else{
	        		CalendarEventEntry targetEvent = entries[0];
	   		         String eventEntryUri = targetEvent.getEditLink().getHref();
	   		         deleteEvent(eventEntryUri, targetEvent.getEtag());
	        	}*/
	        	for (CalendarEventEntry targetEvent: entries)
	        	{
	        		if ((event.getTimes()[0].getStartTime()).equalsTo(targetEvent.getTimes()[0].getStartTime()) 
	        				&& (event.getTimes()[0].getEndTime()).equalsTo(targetEvent.getTimes()[0].getEndTime())
	        				&& (event.getTitle().getText().equalsIgnoreCase(targetEvent.getTitle().getText())))
	        		{
	        			String eventEntryUri = targetEvent.getEditLink().getHref();
	        			deleteEvent(eventEntryUri, targetEvent.getEtag());
	        		}
	        	}

	        }
	      }
	    });
	  }
  
  /**
   * 
   * @param eventsFeedUri The uri of the events feed
   */
  @SuppressWarnings("deprecation")
  public void queryEventsByDate(String eventsFeedUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_QueryEventsByDate");
    showStatus("Querying for events...", false);
    CalendarEventQuery query = CalendarEventQuery.newInstance(eventsFeedUri);
    Date startDate = new Date();
    startDate.setMonth(startDate.getMonth() - 1);
    Date endDate = new Date();
    query.setMinimumStartTime(DateTime.newInstance(startDate));
    query.setMaximumStartTime(DateTime.newInstance(endDate));
    service.getEventsFeed(query, new CalendarEventFeedCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while retrieving the Event feed: " + 
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEventFeed result) {
        CalendarEventEntry[] entries = (CalendarEventEntry[]) result.getEntries();
        if (entries.length == 0) {
          showStatus("No events found for the past month.", false);
        } else {
          showDataQueryEventsByDate(entries);
        }
      }
    });
  }
  /**
   * Retrieves an events feed using a Query object.
   * 
   * @param eventsFeedUri The uri of the events feed
   */
  public void queryEventsFullText(String eventsFeedUri) {
	  service = CalendarService.newInstance("GUoS_Calendar_QueryEventsFullText");
    showStatus("Querying for events...", false);
    CalendarEventQuery query = CalendarEventQuery.newInstance(eventsFeedUri);
    query.setFullTextQuery("GWT-Calendar-Client");
    service.getEventsFeed(query, new CalendarEventFeedCallback() {
      public void onFailure(CallErrorException caught) {
        showStatus("An error occurred while retrieving the Event feed: " + 
            caught.getMessage(), true);
      }
      public void onSuccess(CalendarEventFeed result) {
        CalendarEventEntry[] entries = (CalendarEventEntry[]) result.getEntries();
        if (entries.length == 0) {
          showStatus(
              "No events found containing the text 'GWT-Calendar-Client'.", 
              false);
        } else {
          showDataQueryEventsFullText(entries);
        }
      }
    });
  }
  
  CalendarEntry[] rtGetAllCalendarEntries;
  CalendarEntry[] rtGetAllOwnCalendarEntries;
  
  /**
   * Gets calendars from google
   * @param calendarsFeedUri the users URI
   * @return global value rtGetAllCalendarEntries is updated
   * 		 use this to get all the calendars
   */
  public CalendarEntry[] getAllGoogleCalendars(final String calendarsFeedUri) {
    //showStatus("Loading calendars feed...", false);
	  service = CalendarService.newInstance("GUoS_Calendar_GetAllGCalendars");

    //refresh value set it to null, to get the new one
    rtGetAllCalendarEntries = new CalendarEntry[0];
    
    //Inner class can't return anything can only update global variables
    service.getAllCalendarsFeed(calendarsFeedUri, new CalendarFeedCallback() {
      public void onFailure(CallErrorException caught) {
        //showStatus("An error occurred while retrieving the Calendar feed: " +
           // caught.getMessage(), true);

      }
      
      
      public void onSuccess(CalendarFeed result) {
        CalendarEntry[] entries = result.getEntries();
        
        if (entries.length == 0) {
          showStatus("You have no Calendars.", false);

        } else {
        	rtGetAllCalendarEntries =result.getEntries();

        	//showDataRetrieveCalendars(result.getEntries()); 
        }
      }



  
    });
    return rtGetAllCalendarEntries;
    
  }

    

  public CalendarEntry[] getAllOwnGoogleCalendars(final String ownCalendarsFeedUri) {
	    //showStatus("Loading calendars feed...", false);
		  service = CalendarService.newInstance("GUoS_Calendar_GetAllOwnGCalendars");

	    //refresh value set it to null, to get the new one
	    rtGetAllOwnCalendarEntries = new CalendarEntry[0];
	    Window.alert("Service call to own calendars feed");
	    
	    //Inner class can't return anything can only update global variables
	    service.getOwnCalendarsFeed(ownCalendarsFeedUri, new CalendarFeedCallback() {
	      public void onFailure(CallErrorException caught) {
	    	  Window.alert("Error. "+ caught.getMessage());
	        //showStatus("An error occurred while retrieving the Calendar feed: " +
	           // caught.getMessage(), true);

	      }
	      
	      
	      public void onSuccess(CalendarFeed result) {
	    	  Window.alert("Success. Got results");
	        CalendarEntry[] entries = result.getEntries();
	        
	        if (entries.length == 0) {
	        	Window.alert("No entries found");
	          showStatus("You have no Calendars.", false);
	          rtGetAllOwnCalendarEntries = new CalendarEntry[0];

	        } else {
	        	Window.alert("" + entries.length);
	        	rtGetAllOwnCalendarEntries = entries;

	        	//showDataRetrieveCalendars(result.getEntries()); 
	        }
	      }



	  
	    });
	    //Window.alert("" + rtGetAllOwnCalendarEntries.length);
	    
	    return rtGetAllOwnCalendarEntries;
	    
	  }
  
  
  
  
  /**
   * Displays a set of Calendar event entries in a tabular fashion with
   * the help of a GWT FlexTable widget. The data fields Title, URL 
   * and Updated are displayed.
   * 
   * @param entries The Calendar event entries to display.
   */
   public void showDataRetrieveEvents(CalendarEventEntry[] entries) {
     //loginStatusPanel.clear();
	   loginStatusPanel.refresh();
     String[] labels = new String[] { "Title", "URL", "Updated" };
     loginStatusPanel.insertRow(0);
     for (int i = 0; i < labels.length; i++) {
       loginStatusPanel.addCell(0);
       loginStatusPanel.setWidget(0, i, new Label(labels[i]));
       loginStatusPanel.getFlexCellFormatter().setStyleName(0, i, "hm-tableheader");
     }
     for (int i = 0; i < entries.length; i++) {
       CalendarEventEntry entry = entries[i];
       int row = loginStatusPanel.insertRow(i + 1);
       loginStatusPanel.addCell(row);
       loginStatusPanel.setWidget(row, 0, new Label(entry.getTitle().getText()));
       loginStatusPanel.addCell(row);
       String link = entry.getHtmlLink().getHref();
       loginStatusPanel.setWidget(row, 1,
           new HTML("<a href=\"" + link + "\">" + link + "</a>"));
       loginStatusPanel.addCell(row);
       loginStatusPanel.setWidget(row, 2,
           new Label(entry.getUpdated().getValue().getDate().toString()));
     }
   }
  /**
   * Displays a status message to the user.
   * 
   * @param message The message to display.
   * @param isError Indicates whether the status is an error status.
   */
  public void showStatus(String message, boolean isError) {
    //loginStatusPanel.clear();
	  loginStatusPanel.refresh();
    loginStatusPanel.insertRow(0);
    loginStatusPanel.addCell(0);
    Label msg = new Label(message);
    if (isError) {
      msg.setStylePrimaryName("hm-error");
    }
    loginStatusPanel.setWidget(0, 0, msg);
  }

  /**
   * Displays a set of Calendar event entries in a tabular fashion with
   * the help of a GWT FlexTable widget. The data fields Title, URL 
   * and Updated are displayed.
   * 
   * @param entries The Calendar event entries to display.
   */
   public void showDataQueryEventsFullText(CalendarEventEntry[] entries) {
     //loginStatusPanel.clear();
	   loginStatusPanel.refresh();
     String[] labels = new String[] { "Title", "URL", "Updated" };
     loginStatusPanel.insertRow(0);
     for (int i = 0; i < labels.length; i++) {
       loginStatusPanel.addCell(0);
       loginStatusPanel.setWidget(0, i, new Label(labels[i]));
       loginStatusPanel.getFlexCellFormatter().setStyleName(0, i, "hm-tableheader");
     }
     for (int i = 0; i < entries.length; i++) {
       CalendarEventEntry entry = entries[i];
       int row = loginStatusPanel.insertRow(i + 1);
       loginStatusPanel.addCell(row);
       loginStatusPanel.setWidget(row, 0, new Label(entry.getTitle().getText()));
       loginStatusPanel.addCell(row);
       String link = entry.getHtmlLink().getHref();
       loginStatusPanel.setWidget(row, 1,
           new HTML("<a href=\"" + link + "\">" + link + "</a>"));
       loginStatusPanel.addCell(row);
       loginStatusPanel.setWidget(row, 2,
           new Label(entry.getUpdated().getValue().getDate().toString()));
     }
   }
   /**
    * Displays a set of Calendar entries in a tabular fashion with
    * the help of a GWT FlexTable widget. The data fields Title, Color 
    * and Updated are displayed.
    * 
    * @param entries The Calendar entries to display.
    */
    public void showDataRetrieveCalendars(CalendarEntry[] entries) {
      //loginStatusPanel.clear();
    	loginStatusPanel.refresh();
      String[] labels = new String[] { "Title", "Color", "Updated" };
      loginStatusPanel.insertRow(0);
      for (int i = 0; i < labels.length; i++) {
        loginStatusPanel.addCell(0);
        loginStatusPanel.setWidget(0, i, new Label(labels[i]));
        loginStatusPanel.getFlexCellFormatter().setStyleName(0, i, "hm-tableheader");
      }
      for (int i = 0; i < entries.length; i++) {
        CalendarEntry entry = entries[i];
        int row = loginStatusPanel.insertRow(i + 1);
        loginStatusPanel.addCell(row);
        loginStatusPanel.setWidget(row, 0, new Label(entry.getTitle().getText()));
        loginStatusPanel.addCell(row);
        loginStatusPanel.setWidget(row, 1, new Label(entry.getColor().getValue()));
        loginStatusPanel.addCell(row);
        loginStatusPanel.setWidget(row, 2,
            new Label(entry.getUpdated().getValue().getDate().toString()));
      }
    }
    
    public boolean isLoggedIn(){
        if (User.getStatus(scope) == AuthSubStatus.LOGGED_IN) {
        	return true;
        }else if ((User.getStatus(scope) == AuthSubStatus.LOGGED_OUT)){
        	return false;
        }else
        	return false;
    }
    
    /*public boolean loginCheck(){

    	final ArrayList<Integer> check = new ArrayList<Integer>();
    	String aclUri =  scope + "default/acl/full/default";
    	service = CalendarService.newInstance("GUoS_Calendar_LoginCheck");
    	service.getAclFeed(aclUri, new CalendarAclFeedCallback() {
    	      public void onFailure(CallErrorException caught) {
    	        
    	      }
    	      public void onSuccess(CalendarAclFeed result) {
    	        check.add(1);
    	      }
    	    });
    	if (check.iterator().hasNext())
    		return true;
    	else
    		return false;
    }*/


}